/*
* Copyright (c) 2025 Huawei Device Co., Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including but not limited to the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to provide persons with access to the Software
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGE OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

import React, { useRef, useState, useEffect } from 'react';
import { BreakpointManager, GridRowComponent } from '@hadss/web_adaptive_layout_ui';
import { getBreakpointsAttr, getbreakpointManager } from '../../utils/getBreakpoint';
import { getScopeId } from '../../utils/getScopeId';
import { GutterOption, Gutter, GridRowProps } from '../../types/multiGridRowCol/index'; 

declare global {
  namespace JSX {
    interface IntrinsicElements {
      'grid-row': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
        'columns'?: number | object;
        'gutterX'?: Gutter;
        'gutterY'?: Gutter;
        'breakpointValue'?: string;
        'breakpointRefrence'?: string;
        'direction'?: string;
        scope?: string;
        class?: string;
      }
    }
  }
}

export const MultiGridRow: React.FC<GridRowProps> = (props) => {
  const defaultValue = {
    breakpoints: {
      breakpointValue: { xs: 0, sm: 320, md: 600, lg: 840 },
      breakpointRefrence: 'windowSize',
    }
  };
  const [scopeId, setScopeId] = useState<string>('');
  const gridRef = useRef<GridRowComponent>(null);
  const propsRef = useRef(props);
  const [columns, setColumns] = useState(undefined);
  let gutterValueX;
  let gutterValueY;
  if (props.gutter && typeof props.gutter === 'object') {
    if (props.gutter.hasOwnProperty('x')) {
      gutterValueX = (props.gutter as GutterOption).x;
    }
    if (props.gutter.hasOwnProperty('y')) {
      gutterValueY = (props.gutter as GutterOption).y;
    }
  } else {
    gutterValueX = props.gutter;
    gutterValueY = props.gutter;
  }
  const [gutterX, setGutterX] = useState<Gutter | undefined>(gutterValueX);
  const [gutterY, setGutterY] = useState<Gutter | undefined>(gutterValueY);
  const [breakpointValue, setBreakpointValue] = useState<string>(JSON.stringify(
    props.breakpoints?.breakpointValue || defaultValue.breakpoints.breakpointValue
  ));
  const [breakpointRefrence, setBreakpointRefrence] = useState<string>(props.breakpoints?.breakpointRefrence || defaultValue.breakpoints.breakpointRefrence);
  const [direction, setDirection] = useState(undefined);
  const onGridItemClick = useRef(props.onGridItemClick || (() => { }));
  const onBreakpointChange = useRef(props.onBreakpointChange || ((bp) => { }));
  const breakpointManager = useRef<BreakpointManager>(null);
  const unsubscribe = useRef<Function>(() => {});

  const getCurrentAttr = () => {
    if (propsRef.current.columns !== undefined) {
      setColumns(getBreakpointsAttr(propsRef.current.columns, breakpointManager.current));
    }
    if (propsRef.current.gutter !== undefined) {
      setGutterX(getBreakpointsAttr(gutterX, breakpointManager.current));
      setGutterY(getBreakpointsAttr(gutterY, breakpointManager.current));
    }
    if (propsRef.current.direction !== undefined) {
      setDirection(getBreakpointsAttr(propsRef.current.direction, breakpointManager.current));
    }
  };

  const mountedCustomEvent = new CustomEvent(('gridRowReactMounted'), {
    detail: {message: true},
    bubbles: false,
    composed: true,
  });

  useEffect(() => {
    propsRef.current = props;
    if (breakpointManager.current) {
      getCurrentAttr();
    }
  }, [props]);

  useEffect(() => {
    if (scopeId) {
      breakpointManager.current = getbreakpointManager(
        breakpointRefrence,
        JSON.parse(breakpointValue),
        scopeId
      );
      unsubscribe.current = breakpointManager.current.subscribeToBreakpoint((bp: string) => {
        onBreakpointChange.current(bp);
        getCurrentAttr();
      });

      if (gridRef.current) {
        gridRef.current.registerEvents(onGridItemClick.current);
        gridRef.current.dispatchEvent(mountedCustomEvent);
      }
    }
  }, [scopeId])

  useEffect(() => {
    setScopeId(getScopeId());

    return () => {
      unsubscribe.current();
      breakpointManager.current.destroy();
    }
  }, []);

  return (
    <grid-row
      ref={gridRef}
      scope={scopeId}
      class={`${scopeId} ${props.className}`}
      columns={columns}
      gutterX={gutterX}
      gutterY={gutterY}
      direction={direction}
      breakpointValue={breakpointValue}
      breakpointRefrence={breakpointRefrence}
      >
      {props.children}
    </grid-row>
  )
};

MultiGridRow.displayName = 'MultiGridRow';
